<template>
  <page-meta :root-font-size="fontSize + 'px'"></page-meta>

  <view class="page-container">
    <CustomHeader
      :bgcolor="compatibleModule.topHeaderBgColor"
      :back-method="pageModule.handleOpenBackModal"
      title="随课自检"
      :border-line="false"
    />

    <view
      class="total-time-container"
      :style="{
        height: compatibleModule.excessHeight,
        backgroundColor: compatibleModule.topHeaderBgColor
      }">
      <view class="time">
        <text class="prefix">已用时</text>
        <CountTime v-model:seconds="pageModule.useTime"></CountTime>
      </view>
      <view class="total">
        <text class="prefix">总进度</text>
        <view class="right">
          <text class="current">{{ pageModule.getCurrentProgress() }}</text>
          <text class="sum">/{{ Course.queryParams.totalProgress }}</text>
        </view>
      </view>
    </view>

    <view class="scene-container" :style="{ top: `calc(${ height } + ${ compatibleModule.excessHeight })` }">
      <text class="top-hint">请选择语法正确且意思切合的选项填入空白处，再次点击可以取消选择。</text>
      <view class="content">
        <template v-for="(item, index) in pageModule.pageData" :key="index">
          <text
            v-if="item.str.includes('#')"
            @click="pageModule.handleClickItem(item.str, index)"
            :class="['input', pageModule.currentIndex == index ? 'active' : '']"
            :data-content="item.value">
            {{ item.str }}
          </text>
          <text v-else>{{ item.str }}</text>
        </template>
      </view>

      <view :style="{
        maxHeight: `calc(100vh - ${ height } - ${ compatibleModule.excessHeight })`,
        height: compatibleModule.sidePopupHeight,
        minHeight: compatibleModule.minHeight
      }">
      </view>
    </view>

    <template v-if="popupModule.popupData.length && pageModule.selfAnswerList.length == pageModule.answerList.length">
      <view class="submit-button" @click="pageModule.handleOpenSubmitModal">
        <text>结束作答</text>
      </view>
    </template>

    <template v-if="popupModule.popupData.length">
      <DragSidePopup
        v-model:height="compatibleModule.sidePopupHeight"
        :excess-height="compatibleModule.excessHeight"
        :min-height="compatibleModule.minHeight">
        <template #header>
          <view class="select-header">
            <view class="right">
              <text class="current">{{ pageModule.selfAnswerList.length }}</text>
              <text class="total">/{{ pageModule.answerList.length }}</text>
            </view>
          </view>
        </template>
        <template #content>
          <view class="select-container">
            <template v-for="(item, index) in popupModule.popupData" :key="index">
              <view
                :class="['item', item.className]"
                @click="!item.className && popupModule.handleClickSelectItem(item, index)">
                <text class="number">{{ item.option }}</text>
              </view>
            </template>
          </view>
        </template>
      </DragSidePopup>
    </template>

    <CwCommon></CwCommon>
  </view>
</template>

<script lang="ts" setup>
  import { ref, reactive } from "vue";
  import { rootFontSize, replaceChar, sortLetter, util } from "@/utils/util";
  import CustomHeader from "@/components/customHeader.vue";
  import DragSidePopup from '@/components/dragSidePopup.vue';
  import API from "@/api";
  import CountTime from "@/components/countTime.vue";
  import { getAnyApp } from "@/common/hooks";
  import { Course, CoursePageEnum } from "@/pages/selfInspection/index";

  type Options = { className: string, op_idx: string, option: string };

  type PageData = { className?: string, str: string, value: string };

  interface Props {
    time: string | number;
  }

  const props = withDefaults(defineProps<Props>(), {
    time: 0
  });

  // 公用常量
  const { CHEESE } = getAnyApp();

  const fontSize = rootFontSize();

  const height = ref(getApp().globalData!.pageTop);

  /**
   * 页面数据模块
   */
  const pageModule = reactive({
    time: 0,
    useTime: 0,
    pageData: [] as PageData[],
    currentIndex: -1,
    currentValue: '',
    selfAnswerList: [] as { selectId: string, value: string, answerId: string }[],
    answerList: [],
    async init(callback?: Function) {
      let selectData = [];
      try {
        const gapFillData: any = await API.getCourseAnswerData({
          section_id: Course.sectionId,
          content_id: Course.data[CoursePageEnum.GAP].content_id
        });
        const [list, maxLength] = this.getFormatOptionData(sortLetter(gapFillData?.topicData?.options, 'op_idx'));
        selectData = list;
        this.answerList = gapFillData?.topicData?.topic || [];
        this.pageData = this.getFormatHtmlData(gapFillData?.topicData?.content, this.answerList, maxLength);
      } catch (e) {
        console.error(e);
      } finally {
        callback && callback(selectData);
      }
      this.initCountTime();
    },
    initCountTime() {
      this.time = Number(props.time || Course.queryParams.time);
      this.useTime = this.time;
    },
    handleOpenSubmitModal() {
      util.showModal({
        isShowModal: true,
        title: "提交答案后不可更改, 确认提交吗",
        cancelBtnText: '再做会',
        confirmBtnText: '提交',
        success: async (e: any) => {
          const answer = pageModule.selfAnswerList.map((item) => {
            const index = item.answerId.substring(item.answerId.lastIndexOf('#') + 1, item.answerId.length);
            const obj: any = pageModule.answerList.find((item: any) => item.idx == index);
            return {
              topic_id: obj && obj.topic_id,
              answer: item.selectId
            }
          });
          try {
            let params = {
              section_id: Course.sectionId,
              content_id: Course.data[CoursePageEnum.GAP].content_id,
              time_long: pageModule.useTime - pageModule.time,
              answer
            }
            await API.setCourseAnswerReport(params);
            CHEESE.Router.redirectTo({
              url: CHEESE.Router.Home.selfInspectionResult,
              params: {
                is_not_root: 0
              }
            });
          } catch (e) {
            console.error(e);
          }
        }
      });
    },
    handleOpenBackModal() {
      util.showModal({
        isShowModal: true,
        title: "现在退出不会保留进度,确定退出?",
        success: (e) => {
          uni.navigateBack({
            delta: 1,
          });
        }
      });
    },
    handleClickItem(str: string, index: number) {
      if (this.currentIndex == index) return;
      this.currentIndex = index;
      this.currentValue = str;
      this.pageData[this.currentIndex].value = '';
      const answerId = this.pageData[this.currentIndex].str;
      const selfAnswerIndex: number = this.selfAnswerList.findIndex((item: any) => item.answerId == answerId);
      if (!~selfAnswerIndex) return;
      popupModule.popupData.find((item: any) => item.op_idx == this.selfAnswerList[selfAnswerIndex].selectId)!.className = '';
      this.selfAnswerList.splice(selfAnswerIndex, 1);
    },
    getFormatHtmlData(str: string, answer_list: any[], maxLength: number) {
      let newList: any[] = [], mapKey = [];
      if (str && answer_list?.length) {
        const list = answer_list.reverse();
        for (let i = 0; i < list.length; i++) {
          let placeholder = '';
          let area = JSON.parse(list[i].answer_seat);
          let id = list[i].idx.toString();
          let placeholderLength = maxLength - id.toString().length;
          for (let i = 0; i < placeholderLength; i++) placeholder += '#';
          mapKey.push(placeholder + id);
          str = replaceChar(str, area[0], area[1], '#');
        }
        newList = str.split('#');
        let startIndex = 1;
        for (let i = mapKey.length - 1; i >= 0 ; i--) {
          newList.splice(startIndex, 0, mapKey[i]);
          startIndex += 2;
        }
      }
      return newList.map((str, index) => {
        //初始化选项
        if (str.includes('#') && !this.currentValue) {
          this.currentIndex = index;
          this.currentValue = str;
        }
        return {
          value: '',
          str
        }
      });
    },
    getCurrentProgress() {
      const total_progress = Number(Course.queryParams.totalProgress) ?? 0;
      return total_progress - this.answerList.length + this.selfAnswerList.length;
    },
    getFormatOptionData(list: Options[] = []): [any[], number] {
      let maxLength = 0;
      list.forEach((item) => {
        item.className = '';
        item.option = item.op_idx + ')' + item.option.split(' ')[1];
        item.option.length > maxLength && (maxLength = item.option.length);
      });
      return [list, maxLength];
    }
  });

  // 兼容页面样式模块
  const compatibleModule = reactive({
    sidePopupHeight: '40rem',
    minHeight: '15rem',
    excessHeight: '3rem',
    topHeaderBgColor: '#FDF2E0'
  });

  /**
   * 弹窗模块
   */
  const popupModule = reactive({
    popupData: [] as Options[],
    init(selectData: Options[]) {
      this.popupData = selectData;
    },
    handleClickSelectItem(data: { op_idx: string, option: string }, index: number) {
      if (!~pageModule.currentIndex) return;

      const selfAnswerIndex: number = pageModule.selfAnswerList.findIndex((item: any) => item.answerId == pageModule.currentValue);
      const setValue = () => {
        pageModule.pageData[pageModule.currentIndex].value = data.option;
        pageModule.selfAnswerList.push({
          selectId: data.op_idx,
          value: data.option,
          answerId: pageModule.currentValue
        });
        this.popupData[index].className = 'active';
      }

      if (!!~selfAnswerIndex) {
        this.popupData.find((item) => item.op_idx == pageModule.selfAnswerList[selfAnswerIndex].selectId)!.className = '';
        pageModule.selfAnswerList.splice(selfAnswerIndex, 1);
        setValue();
      } else {
        setValue();
      }
    }
  });

  (() => {
    pageModule.init((data: any) => {
      popupModule.init(data);
      pageModule.handleClickItem(pageModule.currentValue, pageModule.currentIndex);
    });
  })();
</script>

<style scoped lang="scss">
  @mixin fontStyle($size) {
    font-size: #{ $size }rem;
    font-family: xiaolai;
    color: $uni-text-color;
  }

  .page-container {
    width: 100vw;
    height: 100vh;
    background-color: #fff;

    .total-time-container {
      @include fontStyle(1.6);
      display: flex;
      justify-content: center;
      align-items: flex-start;
      position: relative;
      border-bottom: 1px solid #EDDCD7;
      box-sizing: border-box;

      .time {
        display: flex;
        align-items: center;

        .prefix {
          color: $uni-text-color-btn;
          margin-right: 0.5rem;
        }
      }

      .total {
        @include fontStyle(1.4);
        position: absolute;
        right: 20px;
        display: flex;
        align-items: center;

        .prefix {
          color: $uni-text-color-grey;
        }

        .right {
          text-align: right;
          width: 3rem;

          .current {
            color: $uni-text-color;
          }
          .sum {
            color: $uni-text-color-grey;
          }
        }
      }
    }

    .scene-container {
      position: absolute;
      width: 37.5rem;
      bottom: 0;
      left: 50%;
      transform: translateX(-50%);
      box-sizing: border-box;
      padding: 2rem 20px 0 20px;
      padding-bottom: calc(2rem + constant(safe-area-inset-bottom));
      padding-bottom: calc(2rem + env(safe-area-inset-bottom));
      overflow-y: auto;

      .top-hint {
        @include fontStyle(1.5);
        color: $uni-text-color-grey;
      }

      .content {
        @include fontStyle(1.7);
        margin-top: 1rem;
        line-height: 2.5rem;

        .base {
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
          height: 100%;
          width: 100%;
          background-color: #FFEBCA;
          content: attr(data-content);
          text-align: center;
          line-height: 1;
          padding: 0.3rem 0 0.1rem 0;
        }

        .input {
          position: relative;
          &.active {
            &::after {
              @extend .base;
              border: 1px solid $uni-text-color-grey;
            }
          }
          &::after {
            @extend .base;
            border: 1px solid transparent;
          }
        }
      }
    }

    .select-header {
      display: flex;
      justify-content: flex-end;

      .right {
        @include fontStyle(1.7);
        margin-left: 1rem;
        width: 5.3rem;
        height: 2.2rem;
        line-height: 2.2rem;
        text-align: center;
        border-radius: 1.25rem;
        border: #F9EEDC solid 1px;
        box-sizing: border-box;
        font-size: 1.4rem;

        .current {
          color: #7C2D10;
        }

        .total {
          color: #A87F71;
        }
      }
    }

    .submit-button {
      @include fontStyle(1.7);
      position: fixed;
      height: 5rem;
      width: 31.5rem;
      bottom: calc(2.5rem + constant(safe-area-inset-bottom));
      bottom: calc(2.5rem + env(safe-area-inset-bottom));
      line-height: 5rem;
      text-align: center;
      left: 50%;
      transform: translate(-50%);
      box-sizing: border-box;
      border: 0.2rem solid $uni-btn-border;
      background-color: $uni-btn-prime;
      border-radius: 1rem;
      z-index: 999;
    }

    .select-container {
      @include fontStyle(1.7);
      padding-bottom: calc(10rem + constant(safe-area-inset-bottom));
      padding-bottom: calc(10rem + env(safe-area-inset-bottom));
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-row-gap: 2.4rem;
      grid-column-gap: 1.4rem;
      .item {
        text-align: left;
        height: 2.2rem;
        line-height: 2.2rem;
        min-width: 10.2rem;

        &.active {
          background-color: #FFEBCA;
        }
      }
    }
  }
</style>
